package cn.com.qtgl.sso.oidc.comp.security;

import cn.com.qtgl.oauth2.TokenManager;
import cn.com.qtgl.sso.oidc.comp.service.TokenService;
import cn.com.qtgl.sso.oidc.model.entity.SsoProfile;
import cn.melonlib.authentication.model.entity.Profile;
import cn.melonlib.authentication.model.entity.Tenant;
import cn.melonlib.cores.identification.comp.messenger.IdentificationMessenger;
import cn.melonlib.cores.identification.comp.messenger.MessengerUtils;
import cn.melonlib.cores.identification.comp.messenger.OrganizationManager;
import org.hibernate.service.spi.ServiceException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@ConditionalOnProperty(value = "security.auth.mode",havingValue = "http-authorization",matchIfMissing = false)
public class HttpAuthorizationIdentificationMessenger<PROFILE extends Profile,TENANT extends Tenant> implements IdentificationMessenger<PROFILE, TENANT> {

    private final ThreadLocal<PROFILE> localUser=new ThreadLocal<>();
    private final ThreadLocal<TENANT> localTenant=new ThreadLocal<>();

    @Resource
    @Lazy
    private TokenManager tokenManager;

    @Resource
    @Lazy
    private OrganizationManager<String> tenantManager;



    @Resource
    private TokenService tokenService;

    @Resource
    private MessengerUtils messengerUtils;

    public void initIdentification(){
            localUser.set(this.getLoginUser());
            localTenant.set((TENANT) this.tenantManager.getOrganization());
            messengerUtils.setTenant(tokenService.getTenant());
    }

    @Override
    public PROFILE getIdentification() {
        return localUser.get();
    }

    public void clear(){
        this.localUser.remove();
        this.localTenant.remove();
    }

    @Override
    public TENANT getOrganization() {
        return this.localTenant.get();
    }

    @Override
    public String getToken() {
        return this.tokenService.getClientToken().getAccessToken();
    }


    public PROFILE getLoginUser() {
        try {
            return (PROFILE) new SsoProfile(tokenService.introspect(tokenService.getClientToken().getAccessToken()));
        }catch (Exception e){
            throw new ServiceException(e.getMessage(),e);
        }
    }
}
